home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / iconv8_s.arc / ICONT.ARC / LLEX.C < prev    next >
C/C++ Source or Header  |  1990-03-28  |  8KB  |  359 lines

  1. /*
  2.  * llex.c -- lexical analysis routines.
  3.  */
  4.  
  5. #ifdef CRAY
  6. #include <stdlib.h>
  7. #endif                    /* CRAY */
  8.  
  9. #include <math.h>
  10. #include "..\h\config.h"
  11. #include "general.h"
  12. #include "tproto.h"
  13. #include "link.h"
  14. #include "opcode.h"
  15. #include <ctype.h>
  16.  
  17. int nlflag = 0;        /* newline last seen */
  18.  
  19. #if MACINTOSH
  20. #if MPW
  21. #include <CursorCtl.h>
  22. #define CURSORINTERVAL 100
  23. #endif                    /* MPW */
  24. #endif                    /* MACINTOSH */
  25.  
  26. #if !EBCDIC
  27. #define tonum(c)    (isdigit(c) ? (c - '0') : ((c & 037) + 9))
  28. #endif                    /* !EBCDIC */
  29.  
  30. #if !EBCDIC
  31. /*
  32.  * getopc - get an opcode from infile, return the opcode number (via
  33.  *  binary search of opcode table), and point id at the name of the opcode.
  34.  */
  35. int getopc(id)
  36. char **id;
  37.    {
  38.    register char *s;
  39.    register struct opentry *p;
  40.    register int test;
  41.    int low, high, cmp;
  42.    extern char *getstr();
  43.  
  44.    s = getstr();
  45.    if (s == NULL)
  46.       return EOF;
  47.    low = 0;
  48.    high = NOPCODES;
  49.    do {
  50.       test = (low + high) / 2;
  51.       p = &optable[test];
  52.       if ((cmp = strcmp(p->op_name, s)) < 0)
  53.          low = test + 1;
  54.       else if (cmp > 0)
  55.          high = test;
  56.       else {
  57.          *id = p->op_name;
  58.          return (p->op_code);
  59.          }
  60.       } while (low < high);
  61.    *id = s;
  62.    return 0;
  63.    }
  64. #else                    /* !EBCDIC */
  65. /*
  66.  * getopc - get an opcode from infile, return the opcode number (via
  67.  * sequential search of opcode table) and point id at the name of the opcode.
  68.  */
  69.  
  70. int getopc(id)
  71. char **id;
  72.    {
  73.    register char *s;
  74.    register struct opentry *p;
  75.    register int test;
  76.  
  77.    s = getstr();
  78.    if (s == NULL)
  79.       return EOF;
  80.    for(test=0;test < NOPCODES; test++) {
  81.        p = &optable[test];
  82.        if( strcmp(p->op_name, s) == 0) {
  83.            *id = p->op_name;
  84.            return (p->op_code);
  85.        }
  86.    }
  87.    *id = s;
  88.    return 0;
  89.    }
  90. #endif                    /* !EBCDIC */
  91.  
  92. /*
  93.  * getid - get an identifier from infile, put it in the identifier
  94.  *  table, and return a pointer to it.
  95.  */
  96. char *getid()
  97.    {
  98.    register char *s;
  99.  
  100.    s = getstr();
  101.    if (s == NULL)
  102.       return NULL;
  103.    return putident((int)strlen(s)+1);
  104.    }
  105.  
  106. /*
  107.  * getstr - get an identifier from infile and return a pointer to it.
  108.  */
  109. char *getstr()
  110.    {
  111.    register int c;
  112.    register char *p;
  113.  
  114. #if MACINTOSH
  115. #if MPW
  116.    {
  117.    static short cursorcount = CURSORINTERVAL;
  118.    if (--cursorcount == 0) {
  119.       RotateCursor(-32);
  120.       cursorcount = CURSORINTERVAL;
  121.       }
  122.    }
  123. #endif                    /* MPW */
  124. #endif                    /* MACINTOSH */
  125.  
  126.    p = lsfree;
  127.    while ((c = getc(infile)) == ' ' || c == '\t') ;
  128.    if (c == EOF)
  129.       return NULL;
  130.    while (c != ' ' && c != '\t' && c != '\n' && c != ',' && c != EOF) {
  131.       if (p >= lsend)
  132.          quit("out of string space");
  133.       *p++ = c;
  134.       c = getc(infile);
  135.       }
  136.    *p = 0;
  137.    nlflag = (c == '\n');
  138.    return lsfree;
  139.    }
  140.  
  141. /*
  142.  * getrest - get the rest of the line from infile, put it in the identifier
  143.  *  table, and return a pointer to it.
  144.  */
  145. char *getrest()
  146.    {
  147.    register int c;
  148.    register char *p;
  149.  
  150.    p = lsfree;
  151.    while ((c = getc(infile)) != '\n' && c != EOF) {
  152.       if (p >= lsend)
  153.          quit("out of string space");
  154.       *p++ = c;
  155.       }
  156.    *p = 0;
  157.    nlflag = (c == '\n');
  158.    return putident((int)strlen(lsfree)+1);
  159.    }
  160.  
  161. /*
  162.  * getdec - get a decimal integer from infile, and return it.
  163.  */
  164. int getdec()
  165.    {
  166.    register int c, n;
  167.    int sign = 1;
  168.  
  169.    n = 0;
  170.    while ((c = getc(infile)) == ' ' || c == '\t') ;
  171.    if (c == EOF)
  172.       return 0;
  173.    if (c == '-') {
  174.       sign = -1;
  175.       c = getc(infile);
  176.       }
  177.    while (c >= '0' && c <= '9') {
  178.       n = n * 10 + (c - '0');
  179.       c = getc(infile);
  180.       }
  181.    nlflag = (c == '\n');
  182.    return n*sign;
  183.    }
  184.  
  185. /*
  186.  * getoct - get an octal number from infile, and return it.
  187.  */
  188. int getoct()
  189.    {
  190.    register int c, n;
  191.  
  192.    n = 0;
  193.    while ((c = getc(infile)) == ' ' || c == '\t') ;
  194.    if (c == EOF)
  195.       return 0;
  196.    while (c >= '0' && c <= '7') {
  197.       n = (n << 3) | (c - '0');
  198.       c = getc(infile);
  199.       }
  200.    nlflag = (c == '\n');
  201.    return n;
  202.    }
  203.  
  204. /*
  205.  *  Get integer, but if it's too large for a long, put the string via cp
  206.  *   and return -1.
  207.  */
  208. long getint(j,cp)
  209.    int j;
  210.    char **cp;
  211.    {
  212.    register int c;
  213.    int over = 0;
  214.    register char *p;
  215.    double result = 0;
  216.    long lresult = 0;
  217.    double radix;
  218.  
  219.    if (lsfree + j > lsend)
  220.       quit("out of string space");
  221.    p = lsfree;
  222.    
  223.    while ((c = getc(infile)) >= '0' && c <= '9') {
  224.       *p++ = c;
  225.       result = result * 10 + (c - '0');
  226.       lresult = lresult * 10 + (c - '0');
  227.       if (result <= MinLong || result >= MaxLong) {
  228.          over = 1;            /* flag overflow */
  229.          result = 0;            /* reset to avoid fp exception */
  230.          }
  231.       }
  232.    if (c == 'r' || c == 'R') {
  233.       *p++ = c;
  234.       radix = result;
  235.       lresult = 0;
  236.       result = 0;
  237.       while (c = getc(infile)) {
  238.          *p++ = c;
  239.          if (isdigit(c) || isalpha(c))
  240.             c = tonum(c);
  241.          else
  242.             break;
  243.          result = result * radix + c;
  244.          lresult = lresult * radix + c;
  245.          if (result <= MinLong || result >= MaxLong) {
  246.             over = 1;            /* flag overflow */
  247.             result = 0;            /* reset to avoid fp exception */
  248.             }
  249.          }
  250.       }
  251.    nlflag = (c == '\n');
  252.    if (!over)
  253.       return lresult;            /* integer is small enough */
  254.    else {                /* integer is too large */
  255.       *p++ = 0;
  256.       *cp = putident((int)(p - lsfree));/* convert integer to string */
  257.       return -1;            /* indicate integer is too big */
  258.       }
  259.    }
  260.  
  261. /*
  262.  * getreal - get an Icon real number from infile, and return it.
  263.  */
  264. double getreal()
  265.    {
  266.    double n;
  267.    register int c, d, e;
  268.    int esign;
  269.    register char *s, *ep;
  270.    char cbuf[128];
  271.  
  272.    s = cbuf;
  273.    d = 0;
  274.    while ((c = getc(infile)) == '0')
  275.       ;
  276.    while (c >= '0' && c <= '9') {
  277.       *s++ = c;
  278.       d++;
  279.       c = getc(infile);
  280.       }
  281.    if (c == '.') {
  282.       if (s == cbuf)
  283.          *s++ = '0';
  284.       *s++ = c;
  285.       while ((c = getc(infile)) >= '0' && c <= '9')
  286.          *s++ = c;
  287.       }
  288.    ep = s;
  289.    if (c == 'e' || c == 'E') {
  290.       *s++ = c;
  291.       if ((c = getc(infile)) == '+' || c == '-') {
  292.          esign = (c == '-');
  293.          *s++ = c;
  294.          c = getc(infile);
  295.          }
  296.       e = 0;
  297.       while (c >= '0' && c <= '9') {
  298.          e = e * 10 + c - '0';
  299.          *s++ = c;
  300.          c = getc(infile);
  301.          }
  302.       if (esign) e = -e;
  303.       e += d - 1;
  304.       if (abs(e) >= LogHuge)
  305.          *ep = '\0';
  306.       }
  307.    *s = '\0';
  308.    n = atof(cbuf);
  309.    nlflag = (c == '\n');
  310.    return n;
  311.    }
  312.  
  313. /*
  314.  * getlab - get a label ("L" followed by a number) from infile,
  315.  *  and return the number.
  316.  */
  317.  
  318. int getlab()
  319.    {
  320.    register int c;
  321.  
  322.    while ((c = getc(infile)) != 'L' && c != EOF && c != '\n') ;
  323.    if (c == 'L')
  324.       return getdec();
  325.    nlflag = (c == '\n');
  326.    return 0;
  327.    }
  328.  
  329. /*
  330.  * getstrlit - get a string literal from infile, as a string
  331.  *  of octal bytes, and return it.
  332.  */
  333. char *getstrlit(l)
  334. register int l;
  335.    {
  336.    register char *p;
  337.  
  338.    if (lsfree + l > lsend)
  339.       quit("out of string space");
  340.    p = lsfree;
  341.    while (!nlflag && l--)
  342.       *p++ = getoct();
  343.    *p++ = 0;
  344.    return putident((int)(p-lsfree));
  345.    }
  346.  
  347. /*
  348.  * newline - skip to next line.
  349.  */
  350. novalue newline()
  351.    {
  352.    register int c;
  353.  
  354.    if (!nlflag) {
  355.       while ((c = getc(infile)) != '\n' && c != EOF) ;
  356.       }
  357.    nlflag = 0;
  358.    }
  359.